package com.mrtan.controller;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.util.SaResult;
import com.mrtan.exceptions.ParamException;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.*;

/**
 * 异常处理
 * @author 聪
 * @date 2023/12/08
 */
@RestControllerAdvice
public class ExceptionController {

    @ExceptionHandler
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public SaResult handler(NotLoginException e) {
        return SaResult.error().setMsg(e.getMessage()).setCode(401);
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public SaResult handler(NotPermissionException e) {
        return SaResult.error().setMsg(e.getMessage()).setCode(403);
    }

    /*@ExceptionHandler(NullPointerException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public SaResult handleNullPointerException(NullPointerException e) {
        // 你可以在这里记录日志或做其他事情
        return SaResult.error("登录失败:用户名或密码错误").setCode(400);
    }*/

    @ExceptionHandler
    public SaResult handler(ParamException e) {
        return SaResult.error().setMsg(e.getMessage()).setCode(e.getCode());
    }

    @ExceptionHandler
    public SaResult handler(ConstraintViolationException e) {
        SaResult result = SaResult.error();
        result.setCode(400);
        result.setMsg("参数校验失败");
        Map<String, List<String>> errors = new HashMap<>();

        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            PathImpl path = (PathImpl) constraintViolation.getPropertyPath();
            String propertyPath = path.getLeafNode().toString();
            String message = constraintViolation.getMessage();
            List<String> o = errors.get(propertyPath);
            if (o == null) {
                o = new ArrayList<>();
                errors.put(propertyPath, o);
            }
            o.add(message);
        }
        return result.setData(errors);
    }


    @ExceptionHandler
    public SaResult handler(BindException e) {
        SaResult result = SaResult.error();
        result.setCode(400);
        result.setMsg("参数校验失败");
        List<FieldError> fieldErrors = e.getFieldErrors();
        Map<String, List<String>> errors = new HashMap<>();
        for (FieldError fieldError : fieldErrors) {
            List<String> o = errors.get(fieldError.getField());
            if (o == null) {
                o = new ArrayList<>();
                errors.put(fieldError.getField(), o);
            }
            o.add(fieldError.getDefaultMessage());
        }
        return result.setData(errors);
    }
}
